home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 October / Macformat17.cdr / Shareware City / Developers / shutdown-fx-201-c / sfx ƒ / sfx control app ƒ / sfx code ƒ / sfx main window.c < prev    next >
Text File  |  1994-07-11  |  17KB  |  575 lines

  1. /**********************************************************************\
  2.  
  3. File:        sfx main window.c
  4.  
  5. Purpose:    This module handles initializing/drawing/dealing with the
  6.             main window.
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program in a file named "GNU General Public License".
  20. If not, write to the Free Software Foundation, 675 Mass Ave,
  21. Cambridge, MA 02139, USA.
  22.  
  23. \**********************************************************************/
  24.  
  25. #include "sfx main window.h"
  26. #include "sfx lists.h"
  27. #include "sfx meat.h"
  28. #include "environment.h"
  29. #include "buttons.h"
  30. #include "util.h"
  31. #include "main.h"
  32. #include "error.h"
  33.  
  34. #define HEADER_SPACE    10
  35. #define DEAD_SPACE_V    10
  36. #define    DEAD_SPACE_H    10
  37. #define    FOOTER_SPACE    10
  38. #define PICTURE_HEIGHT    -10
  39. #define BUTTON_HEIGHT    60
  40. #define    BUTTON_WIDTH    60
  41. #define    LIST_HEIGHT        156
  42. #define LIST_WIDTH        150
  43. #define TITLE_SPACE_V    20
  44.  
  45. /* internal procedures for sfx main window.c only */
  46. static void SetupTheMainWindow(WindowDataHandle theData);
  47. static void ShutDownTheMainWindow(WindowDataHandle theData);
  48. static void InitializeTheMainWindow(WindowDataHandle theData);
  49. static void OpenTheMainWindow(WindowDataHandle theData);
  50. static void CloseTheMainWindow(WindowDataHandle theData);
  51. static void IdleInMainWindow(WindowDataHandle theData);
  52. static void KeyPressedInMainWindow(WindowDataHandle theData, unsigned char theChar);
  53. static void MouseClickedInMainWindow(WindowDataHandle theData, Point thePoint);
  54. static void DisposeTheMainWindow(WindowDataHandle theData);
  55. static void ActivateTheMainWindow(WindowDataHandle theData);
  56. static void DeactivateTheMainWindow(WindowDataHandle theData);
  57. static void DrawTheMainWindow(WindowDataHandle theData, short theDepth);
  58. static void CopybitsTheMainWindow(WindowDataHandle theData);
  59. static void SwitchLists(WindowDataHandle theData, Boolean updateNow);
  60. static enum ErrorTypes PickAModule(void);
  61.  
  62. #define BUTTON_TITLE_ID                200    /* ID of STR# resource of button titles */
  63. #define BUTTON_INACTIVE_TITLE_ID    201
  64. #define    FIRST_BUTTON_ID                200    /* ID of cicn/ICON resource of first button */
  65. #define NUM_BUTTONS                    3
  66.  
  67. enum
  68. {
  69.     kRemoveButton=0, kDemoButton, kInstallButton
  70. };
  71.  
  72. static    short            gOldForegroundTime;        /* stored foreground wait time */
  73. static    short            gDisplayedScore;
  74. static    ListHandle        gUsedList, gNotUsedList;
  75. static    Rect            gUsedListRect, gNotUsedListRect;
  76. static    Boolean            gUsedIsActive;
  77. static    Rect            gButtonRect[NUM_BUTTONS];
  78. static    Str31            gButtonTitle[NUM_BUTTONS];
  79. static    Str31            gButtonInactiveTitle[NUM_BUTTONS];
  80. static    CIconHandle        gButtonIconColor[NUM_BUTTONS];
  81. static    Handle            gButtonIconBW[NUM_BUTTONS];
  82. static    Boolean            gButtonActive[NUM_BUTTONS];
  83. static    short            gNumButtons;
  84. static    Boolean            gImmediateUpdate;
  85.  
  86. short MainWindowDispatch(WindowDataHandle theData, short theMessage,
  87.     unsigned long misc)
  88. {
  89.     short            theDepth;
  90.     unsigned char    theChar;
  91.     Point            thePoint;
  92.     GrafPtr            curPort;
  93.     
  94.     switch (theMessage)
  95.     {
  96.         case kNull:
  97.             IdleInMainWindow(theData);
  98.             return kSuccess;
  99.             break;
  100.         case kUpdate:
  101.             theDepth=misc&0x7fff;
  102.             DrawTheMainWindow(theData, theDepth);
  103.             return kSuccess;
  104.             break;
  105.         case kInitialize:
  106.             InitializeTheMainWindow(theData);
  107.             return kFailure;
  108.         case kOpen:
  109.             OpenTheMainWindow(theData);
  110.             return kSuccess;
  111.             break;
  112.         case kClose:
  113.             CloseTheMainWindow(theData);
  114.             return kSuccess;
  115.             break;
  116.         case kKeydown:
  117.             theChar=misc&charCodeMask;
  118.             KeyPressedInMainWindow(theData, theChar);
  119.             return kSuccess;
  120.             break;
  121.         case kMousedown:
  122.              thePoint.h=(misc>>16)&0x7fff;
  123.              thePoint.v=misc&0x7fff;
  124.              MouseClickedInMainWindow(theData, thePoint);
  125.              return kSuccess;
  126.              break;
  127.          case kActivate:
  128.              ActivateTheMainWindow(theData);
  129.              return kSuccess;
  130.              break;
  131.          case kDeactivate:
  132.              DeactivateTheMainWindow(theData);
  133.              return kSuccess;
  134.              break;
  135.         case kStartup:
  136.             SetupTheMainWindow(theData);
  137.             return kSuccess;
  138.             break;
  139.         case kDispose:
  140.             DisposeTheMainWindow(theData);
  141.             return kSuccess;
  142.             break;
  143.         case kShutdown:
  144.             ShutDownTheMainWindow(theData);
  145.             return kSuccess;
  146.             break;
  147.         case kCopybits:
  148.             CopybitsTheMainWindow(theData);
  149.             return kSuccess;
  150.     }
  151.     
  152.     return kFailure;
  153. }
  154.  
  155. void SetupTheMainWindow(WindowDataHandle theData)
  156. {
  157.     unsigned char    *titleStr="\pShutdown FX";
  158.     short            i;
  159.     
  160.     gButtonRect[kInstallButton].left=DEAD_SPACE_H*3+LIST_WIDTH;
  161.     gButtonRect[kInstallButton].top=HEADER_SPACE+PICTURE_HEIGHT+DEAD_SPACE_V*2+TITLE_SPACE_V;
  162.     gButtonRect[kInstallButton].right=gButtonRect[kInstallButton].left+BUTTON_WIDTH;
  163.     gButtonRect[kInstallButton].bottom=gButtonRect[kInstallButton].top+BUTTON_HEIGHT;
  164.     i=(LIST_HEIGHT-(DEAD_SPACE_V*2+BUTTON_HEIGHT*2))/2;
  165.     OffsetRect(&gButtonRect[kInstallButton], 0, i);
  166.     gButtonRect[kRemoveButton]=gButtonRect[kDemoButton]=gButtonRect[kInstallButton];
  167.     OffsetRect(&gButtonRect[kDemoButton], 0, BUTTON_HEIGHT+DEAD_SPACE_V*2);
  168.     for (i=0; i<NUM_BUTTONS; i++)
  169.     {
  170.         GetIndString(gButtonTitle[i], BUTTON_TITLE_ID, i+1);
  171.         GetIndString(gButtonInactiveTitle[i], BUTTON_INACTIVE_TITLE_ID, i+1);
  172.         gButtonActive[i]=FALSE;
  173.         if (gHasColorQD)
  174.             gButtonIconColor[i]=GetCIcon(FIRST_BUTTON_ID+i);
  175.         gButtonIconBW[i]=GetIcon(FIRST_BUTTON_ID+i);
  176.     }
  177.     gNumButtons=NUM_BUTTONS-1;
  178.     
  179.     (**theData).maxDepth=8;
  180.     (**theData).windowType=noGrowDocProc;
  181.     (**theData).hasCloseBox=TRUE;
  182.     (**theData).windowWidth=DEAD_SPACE_H*6+LIST_WIDTH*2+BUTTON_WIDTH;
  183.     (**theData).windowHeight=HEADER_SPACE+PICTURE_HEIGHT+TITLE_SPACE_V+LIST_HEIGHT+
  184.         DEAD_SPACE_V*2+FOOTER_SPACE;
  185.     SetIndWindowTitle((**theData).windowIndex, titleStr);
  186.     OpenTheWindow(theData);
  187. }
  188.  
  189. void ShutDownTheMainWindow(WindowDataHandle theData)
  190. {
  191.     if (gModuleName[0]==0x00)
  192.         HandleError(PickAModule(), FALSE, FALSE);
  193. }
  194.  
  195. void InitializeTheMainWindow(WindowDataHandle theData)
  196. {
  197. }
  198.  
  199. void OpenTheMainWindow(WindowDataHandle theData)
  200. {
  201.     GetWindowGrafPtr(theData)->txFont=geneva;
  202.     GetWindowGrafPtr(theData)->txSize=9;
  203.     
  204.     gUsedListRect.left=DEAD_SPACE_H;
  205.     gUsedListRect.top=HEADER_SPACE+PICTURE_HEIGHT+DEAD_SPACE_V*2+TITLE_SPACE_V;
  206.     gUsedListRect.right=gUsedListRect.left+LIST_WIDTH;
  207.     gUsedListRect.bottom=gUsedListRect.top+LIST_HEIGHT;
  208.     gUsedList=MyCreateVerticalScrollingList(GetWindowGrafPtr(theData), gUsedListRect,
  209.         1, 0);
  210.     (**gUsedList).selFlags=lExtendDrag+lNoRect+lUseSense;
  211.     gNotUsedListRect=gUsedListRect;
  212.     OffsetRect(&gNotUsedListRect, LIST_WIDTH+DEAD_SPACE_H*4+BUTTON_WIDTH, 0);
  213.     gNotUsedList=MyCreateVerticalScrollingList(GetWindowGrafPtr(theData), gNotUsedListRect,
  214.         1, 0);
  215.     (**gNotUsedList).selFlags=lExtendDrag+lNoRect+lUseSense;
  216.     gUsedIsActive=TRUE;
  217.     gImmediateUpdate=TRUE;
  218.     HandleError(MakeNewLists(FALSE), TRUE, FALSE);
  219. }
  220.  
  221. void CloseTheMainWindow(WindowDataHandle theData)
  222. {
  223.     HandleError(PickAModule(), FALSE, FALSE);
  224.     
  225.     LDispose(gUsedList);
  226.     LDispose(gNotUsedList);
  227. }
  228.  
  229. void IdleInMainWindow(WindowDataHandle theData)
  230. {
  231. }
  232.  
  233. void KeyPressedInMainWindow(WindowDataHandle theData, unsigned char theChar)
  234. {
  235.     EventRecord        theEvent;
  236.     
  237.     GetCurrentEvent(&theEvent);
  238.     
  239.     switch (theChar)
  240.     {
  241.         case '\t':
  242.             SwitchLists(theData, TRUE);
  243.             break;
  244.         case 0x01:        /* home */
  245.             if (gUsedIsActive)
  246.                 LScroll(0, -((**gUsedList).dataBounds.bottom), gUsedList);
  247.             else
  248.                 LScroll(0, -((**gNotUsedList).dataBounds.bottom), gNotUsedList);
  249.             break;
  250.         case 0x04:        /* end */
  251.             if (gUsedIsActive)
  252.                 LScroll(0, ((**gUsedList).dataBounds.bottom), gUsedList);
  253.             else
  254.                 LScroll(0, ((**gNotUsedList).dataBounds.bottom), gNotUsedList);
  255.             break;
  256.         case 0x0b:        /* page up */
  257.             if (gUsedIsActive)
  258.                 LScroll(0, -(**gUsedList).visible.bottom+(**gUsedList).visible.top+1, gUsedList);
  259.             else
  260.                 LScroll(0, -(**gNotUsedList).visible.bottom+(**gNotUsedList).visible.top+1, gNotUsedList);
  261.             break;
  262.         case 0x0c:        /* page down */
  263.             if (gUsedIsActive)
  264.                 LScroll(0, (**gUsedList).visible.bottom-(**gUsedList).visible.top-1, gUsedList);
  265.             else
  266.                 LScroll(0, (**gNotUsedList).visible.bottom-(**gNotUsedList).visible.top-1, gNotUsedList);
  267.             break;
  268.         case 0x1e:        /* up arrow */
  269.             if (gUsedIsActive)
  270.                 LScroll(0, -1, gUsedList);
  271.             else
  272.                 LScroll(0, -1, gNotUsedList);
  273.             break;
  274.         case 0x1f:        /* down arrow */
  275.             if (gUsedIsActive)
  276.                 LScroll(0, 1, gUsedList);
  277.             else
  278.                 LScroll(0, 1, gNotUsedList);
  279.             break;
  280.         default:
  281.             if (theEvent.modifiers & cmdKey)
  282.             {
  283.                 switch (theChar)
  284.                 {
  285.                     case 'd':
  286.                     case 'D':
  287.                         if (gButtonActive[kDemoButton])
  288.                         {
  289.                             Hit3DButton(&gButtonRect[kDemoButton], gButtonTitle[kDemoButton],
  290.                                 ((**theData).windowDepth>2) ? (Handle)gButtonIconColor[kDemoButton] :
  291.                                 gButtonIconBW[kDemoButton], (**theData).windowDepth);
  292.                             HandleError(DoTheDemoFade(gUsedIsActive ? gUsedList : gNotUsedList), FALSE, FALSE);
  293.                         }
  294.                         break;
  295.                     case 'i':
  296.                     case 'I':
  297.                         if ((!gUsedIsActive) && (gButtonActive[kInstallButton]))
  298.                         {
  299.                             Hit3DButton(&gButtonRect[kInstallButton], gButtonTitle[kInstallButton],
  300.                                 ((**theData).windowDepth>2) ? (Handle)gButtonIconColor[kInstallButton] :
  301.                                 gButtonIconBW[kInstallButton], (**theData).windowDepth);
  302.                             HandleError(DoTheInstall(theData, gUsedList, gNotUsedList), FALSE, FALSE);
  303.                             gButtonActive[kRemoveButton]=gButtonActive[kInstallButton]=
  304.                                 gButtonActive[kDemoButton]=FALSE;
  305.                             (**theData).offscreenNeedsUpdate=TRUE;
  306.                             UpdateTheWindow(theData);
  307.                         }
  308.                         break;
  309.                     case 'r':
  310.                     case 'R':
  311.                         if ((gUsedIsActive) && (gButtonActive[kRemoveButton]))
  312.                         {
  313.                             Hit3DButton(&gButtonRect[kRemoveButton], gButtonTitle[kRemoveButton],
  314.                                 ((**theData).windowDepth>2) ? (Handle)gButtonIconColor[kRemoveButton] :
  315.                                 gButtonIconBW[kRemoveButton], (**theData).windowDepth);
  316.                             HandleError(DoTheRemove(theData, gUsedList, gNotUsedList), FALSE, FALSE);
  317.                             gButtonActive[kRemoveButton]=gButtonActive[kInstallButton]=
  318.                                 gButtonActive[kDemoButton]=FALSE;
  319.                             (**theData).offscreenNeedsUpdate=TRUE;
  320.                             UpdateTheWindow(theData);
  321.                         }
  322.                         break;
  323.                 }
  324.             }
  325.     }
  326. }
  327.  
  328. void MouseClickedInMainWindow(WindowDataHandle theData, Point thePoint)
  329. {
  330.     EventRecord        theEvent;
  331.     short            i;
  332.     Cell            theCell;
  333.     Boolean            updateNow;
  334.     
  335.     GetCurrentEvent(&theEvent);
  336.     updateNow=FALSE;
  337.     if (PtInRect(thePoint, &gUsedListRect))
  338.     {
  339.         if (!gUsedIsActive)
  340.         {
  341.             SwitchLists(theData, FALSE);
  342.             updateNow=TRUE;
  343.         }
  344.         MyHandleMouseDownInList(theData, gUsedList, &theEvent, TRUE);
  345.         if ((!gButtonActive[kRemoveButton]) &&
  346.             (MyGetFirstSelectedCell(gUsedList, &theCell)))
  347.         {
  348.             gButtonActive[kRemoveButton]=gButtonActive[kDemoButton]=TRUE;
  349.             (**theData).offscreenNeedsUpdate=updateNow=TRUE;
  350.         }
  351.         else if ((gButtonActive[kRemoveButton]) &&
  352.                 (!MyGetFirstSelectedCell(gUsedList, &theCell)))
  353.         {
  354.             gButtonActive[kRemoveButton]=gButtonActive[kDemoButton]=FALSE;
  355.             (**theData).offscreenNeedsUpdate=updateNow=TRUE;
  356.         }
  357.         if (updateNow)
  358.         {
  359.             UpdateTheWindow(theData);
  360.         }
  361.     }
  362.     else if (PtInRect(thePoint, &gNotUsedListRect))
  363.     {
  364.         if (gUsedIsActive)
  365.         {
  366.             SwitchLists(theData, FALSE);
  367.             updateNow=TRUE;
  368.         }
  369.         MyHandleMouseDownInList(theData, gNotUsedList, &theEvent, FALSE);
  370.         if ((!gButtonActive[kInstallButton]) &&
  371.             (MyGetFirstSelectedCell(gNotUsedList, &theCell)))
  372.         {
  373.             gButtonActive[kInstallButton]=gButtonActive[kDemoButton]=TRUE;
  374.             (**theData).offscreenNeedsUpdate=updateNow=TRUE;
  375.         }
  376.         else if ((gButtonActive[kInstallButton]) &&
  377.                 (!MyGetFirstSelectedCell(gNotUsedList, &theCell)))
  378.         {
  379.             gButtonActive[kInstallButton]=gButtonActive[kDemoButton]=FALSE;
  380.             (**theData).offscreenNeedsUpdate=updateNow=TRUE;
  381.         }
  382.         if (updateNow)
  383.         {
  384.             UpdateTheWindow(theData);
  385.         }
  386.     }
  387.     else
  388.     {
  389.         for (i=gNumButtons-1; i>=0; i--)
  390.         {
  391.             if ((PtInRect(thePoint, &gButtonRect[i])) && (gButtonActive[i]))
  392.             {
  393.                 if (Track3DButton(&gButtonRect[i], gButtonTitle[i],
  394.                     ((**theData).windowDepth>2) ? (Handle)gButtonIconColor[i] :
  395.                     gButtonIconBW[i], (**theData).windowDepth))
  396.                 {
  397.                     switch (i)
  398.                     {
  399.                         case kRemoveButton:
  400.                             HandleError(DoTheRemove(theData, gUsedList, gNotUsedList), FALSE, FALSE);
  401.                             gButtonActive[kRemoveButton]=gButtonActive[kInstallButton]=
  402.                                 gButtonActive[kDemoButton]=FALSE;
  403.                             (**theData).offscreenNeedsUpdate=TRUE;
  404.                             UpdateTheWindow(theData);
  405.                             break;
  406.                         case kDemoButton:
  407.                             HandleError(DoTheDemoFade(gUsedIsActive ? gUsedList : gNotUsedList), FALSE, FALSE);
  408.                             break;
  409.                         case kInstallButton:
  410.                             HandleError(DoTheInstall(theData, gUsedList, gNotUsedList), FALSE, FALSE);
  411.                             gButtonActive[kRemoveButton]=gButtonActive[kInstallButton]=
  412.                                 gButtonActive[kDemoButton]=FALSE;
  413.                             (**theData).offscreenNeedsUpdate=TRUE;
  414.                             UpdateTheWindow(theData);
  415.                             break;
  416.                     }
  417.                 }
  418.             }
  419.         }
  420.     }
  421. }
  422.  
  423. void DisposeTheMainWindow(WindowDataHandle theData)
  424. {
  425. }
  426.  
  427. void ActivateTheMainWindow(WindowDataHandle theData)
  428. {
  429.     gOldForegroundTime=gForegroundWaitTime;
  430.     gForegroundWaitTime=0;
  431.     LActivate(TRUE, gUsedList);
  432.     LActivate(TRUE, gNotUsedList);
  433.     MyDrawActiveListBorder(gUsedList, gUsedIsActive);
  434.     MyDrawActiveListBorder(gNotUsedList, !gUsedIsActive);
  435. }
  436.  
  437. void DeactivateTheMainWindow(WindowDataHandle theData)
  438. {
  439.     gForegroundWaitTime=gOldForegroundTime;
  440.     LActivate(FALSE, gUsedList);
  441.     LActivate(FALSE, gNotUsedList);
  442.     MyDrawActiveListBorder(gUsedList, FALSE);
  443.     MyDrawActiveListBorder(gNotUsedList, FALSE);
  444. }
  445.  
  446. void DrawTheMainWindow(WindowDataHandle theData, short theDepth)
  447. {
  448.     RGBColor        oldForeColor, oldBackColor;
  449.     GrafPtr            curPort;
  450.     short            i;
  451.     
  452.     if (theDepth>2)
  453.     {
  454.         GetForeColor(&oldForeColor);
  455.         GetBackColor(&oldBackColor);
  456.     }
  457.     
  458.     GetPort(&curPort);
  459.     EraseRect(&(curPort->portRect));
  460.     
  461.     for (i=0; i<gNumButtons; i++)
  462.         Draw3DButton(&gButtonRect[i], gButtonActive[i] ? gButtonTitle[i] :
  463.             gButtonInactiveTitle[i], (theDepth>2) ?
  464.             (Handle)gButtonIconColor[i] : gButtonIconBW[i], theDepth, FALSE);
  465.     
  466.     MoveTo(DEAD_SPACE_H, HEADER_SPACE+PICTURE_HEIGHT+DEAD_SPACE_V+TITLE_SPACE_V-3);
  467.     DrawString("\pCurrently available fade modules:");
  468.     
  469.     MoveTo(DEAD_SPACE_H*5+LIST_WIDTH+BUTTON_WIDTH, HEADER_SPACE+PICTURE_HEIGHT+DEAD_SPACE_V+TITLE_SPACE_V-3);
  470.     DrawString("\pCurrently disabled fade modules:");
  471.     
  472.     if (theDepth>2)
  473.     {
  474.         RGBForeColor(&oldForeColor);
  475.         RGBBackColor(&oldBackColor);
  476.     }
  477. }
  478.  
  479. void CopybitsTheMainWindow(WindowDataHandle theData)
  480. {
  481.     RgnHandle        copyRgn;
  482.     RgnHandle        listRgn;
  483.     
  484.     copyRgn=NewRgn();
  485.     listRgn=NewRgn();
  486.     RectRgn(copyRgn, &(GetWindowGrafPtr(theData)->portRect));
  487.     RectRgn(listRgn, &gUsedListRect);
  488.     InsetRgn(listRgn, -4, -4);
  489.     DiffRgn(copyRgn, listRgn, copyRgn);
  490.     SetEmptyRgn(listRgn);
  491.     RectRgn(listRgn, &gNotUsedListRect);
  492.     InsetRgn(listRgn, -4, -4);
  493.     DiffRgn(copyRgn, listRgn, copyRgn);
  494.     
  495.     CopyBits(&(GetOffscreenGrafPtr(theData)->portBits),
  496.         &(GetWindowGrafPtr(theData)->portBits),
  497.         &(GetWindowGrafPtr(theData)->portRect),
  498.         &(GetWindowGrafPtr(theData)->portRect), 0, copyRgn);
  499.     DisposeRgn(copyRgn);
  500.     DisposeRgn(listRgn);
  501.     
  502.     LUpdate(GetWindowGrafPtr(theData)->visRgn, gUsedList);
  503.     MyDrawListBorder(gUsedList);
  504.     MyDrawActiveListBorder(gUsedList, gUsedIsActive);
  505.     LUpdate(GetWindowGrafPtr(theData)->visRgn, gNotUsedList);
  506.     MyDrawListBorder(gNotUsedList);
  507.     MyDrawActiveListBorder(gNotUsedList, !gUsedIsActive);
  508. }
  509.  
  510. enum ErrorTypes MakeNewLists(Boolean updateNow)
  511. {
  512.     enum ErrorTypes    resultCode;
  513.     
  514.     LDoDraw(FALSE, gUsedList);
  515.     LDoDraw(FALSE, gNotUsedList);
  516.     resultCode=SetUpLists(gUsedList, gNotUsedList);
  517.     if (resultCode!=allsWell)
  518.         return resultCode;
  519.     LDoDraw(TRUE, gUsedList);
  520.     LDoDraw(TRUE, gNotUsedList);
  521.     if (updateNow)
  522.     {
  523.         MyUpdateList(gUsedList);
  524.         MyUpdateList(gNotUsedList);
  525.     }
  526.     
  527.     return allsWell;
  528. }
  529.  
  530. void SwitchLists(WindowDataHandle theData, Boolean updateNow)
  531. {
  532.     if (gUsedIsActive)
  533.     {
  534.         MyDeselectAllCells(gUsedList);
  535.         gNumButtons++;
  536.     }
  537.     else
  538.     {
  539.         MyDeselectAllCells(gNotUsedList);
  540.         gNumButtons--;
  541.     }
  542.     gButtonActive[kRemoveButton]=gButtonActive[kInstallButton]=
  543.         gButtonActive[kDemoButton]=FALSE;
  544.     gUsedIsActive=!gUsedIsActive;
  545.     (**theData).offscreenNeedsUpdate=TRUE;
  546.     if (updateNow)
  547.     {
  548.         UpdateTheWindow(theData);
  549.     }
  550. }
  551.  
  552. enum ErrorTypes PickAModule(void)
  553. {
  554.     Cell            theCell;
  555.     
  556.     if ((gUsedList==0L) || ((**gUsedList).dataBounds.bottom==0))
  557.         return kNoModulesInstalled;
  558.     
  559.     if (gChooseRandom)
  560.     {
  561.         gModuleIndex=(Random()&0x7fff)%((**gUsedList).dataBounds.bottom);
  562.     }
  563.     else
  564.     {
  565.         while (gModuleIndex>=(**gUsedList).dataBounds.bottom)
  566.             gModuleIndex-=(**gUsedList).dataBounds.bottom;
  567.         if (gModuleIndex<0)
  568.             gModuleIndex=0;
  569.     }
  570.     SetPt(&theCell, 0, gModuleIndex);
  571.     MyGetCellData(gUsedList, theCell, gModuleName);
  572.     
  573.     return allsWell;
  574. }
  575.